//! @Author: DengLibin 榆霖
//! @Date:  2022-04-20 18:09:13
//! @Description:

use std::{cell::Cell, sync::{atomic::{AtomicUsize, Ordering}, Mutex}};

use actix_web::{
    get,
    http::{header::ContentType, StatusCode},
     HttpRequest, HttpResponse, Responder, Result, Scope, web::{self, Data},
};

use actix_files::NamedFile;
use actix_session::Session;

use common::date;


/// @Author: DengLibin 榆霖
/// @Date:  2022-04-21 11:33:01
/// @Description: 路由配置
pub fn route() -> Scope{
    info!("sys_controller配置路由");
    let sys_scope = web::scope("/sys");
    sys_scope
    .service(favicon)
    .service(welcome)
    .service(time)
    .service(global_count)
}


/// @Author: DengLibin 榆霖
/// @Date:  2022-04-20 18:37:55
/// @Description: 访问文件
#[get("/favicon")]
pub async fn favicon() -> Result<impl Responder> {
    Ok(NamedFile::open("static/favicon.ico")?)
}

/// @Author: DengLibin 榆霖
/// @Date:  2022-04-20 18:38:12
/// @Description: session 访问计数
#[get("/welcome")]
pub async fn welcome(_: HttpRequest, session: Session) -> Result<HttpResponse> {
    //println!("{:?}", req);
    // session
    let mut counter = 1;
    if let Some(count) = session.get::<i32>("counter")? { //也会从Cookie中读取
        info!("count:{}", count);
        counter = count + 1;
    }

    // set counter to session
    session.insert("counter", counter)?;
    let body = format!("<h1>Welcome</h1> {}", counter);
    // response
    Ok(HttpResponse::build(StatusCode::OK)
        .content_type(ContentType::html())
        .body(body))
}
/// @Author: DengLibin 榆霖
/// @Date:  2022-04-20 21:03:39
/// @Description: 获取系统时间
#[get("/time")]
pub async fn time() -> Result<HttpResponse> {

    let body = date::get_chrono_local_now_time_str();
    // response
    Ok(HttpResponse::build(StatusCode::OK)
        .content_type(ContentType::plaintext())
        .body(body))
}
/// @Author: DengLibin 榆霖
/// @Date:  2022-06-30 15:32:04
/// @Description: 全局参数
#[get("/global_count")]
pub async fn global_count(
    counter_mutex: Data<Mutex<usize>>, //作为参数传过来
    counter_cell: Data<Cell<u32>>,
    counter_atomic: Data<AtomicUsize>,
    req: HttpRequest,
) ->  Result<HttpResponse> {
    println!("{:?}", req);

    *counter_mutex.lock().unwrap() += 1;
    counter_cell.set(counter_cell.get() + 1);
    counter_atomic.fetch_add(1, Ordering::SeqCst);

    let body = format!(
        "global mutex counter: {}, local counter: {}, global atomic counter: {}",
        *counter_mutex.lock().unwrap(),
        counter_cell.get(),
        counter_atomic.load(Ordering::SeqCst),
    );
    Ok(HttpResponse::Ok().body(body))
}